package com.crazymaker.springcloud.websocket.netty.handler;

import com.crazymaker.springcloud.common.dto.UserDTO;
import com.crazymaker.springcloud.websocket.netty.event.SecurityCheckCompleteEvent;
import com.crazymaker.springcloud.websocket.processer.MsgProcesser;
import com.crazymaker.springcloud.websocket.session.ServerSession;
import com.crazymaker.springcloud.websocket.session.SessionManager;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * Created by 尼恩 @ 疯狂创客圈
 * <p>
 * WebSocket 帧：WebSocket 以帧的方式传输数据，每一帧代表消息的一部分。一个完整的消息可能会包含许多帧
 */
@Slf4j
public class PusMsgWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //增加消息的引用计数（保留消息），并将他写到 ChannelGroup 中所有已经连接的客户端

        ServerSession session = ServerSession.getSession(ctx);
        String result = MsgProcesser.getSingleton().onMessage(msg.text(), session);

        if (result != null) {
            SessionManager.getSingleton().sendMsg(ctx, result);

        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //是否握手成功，升级为 Websocket 协议
        if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
            // 握手成功，移除 HttpRequestHandler，因此将不会接收到任何消息
            // 并把握手成功的 Channel 加入到 ChannelGroup 中
            ServerSession session = ServerSession.getSession(ctx);
            if (null == session) {
                String ack = MsgProcesser.getSingleton().onSystemError(session);
                SessionManager.getSingleton().closeSessionAfterAck(session, ack);
                return;
            }
            //提示登陆成功
            String ack = MsgProcesser.getSingleton().onOpen(session);
            SessionManager.getSingleton().sendMsg(ctx, ack);

        } else if (evt instanceof IdleStateEvent) {
            IdleStateEvent stateEvent = (IdleStateEvent) evt;
            if (stateEvent.state() == IdleState.READER_IDLE) {
                ServerSession session = ServerSession.getSession(ctx);
                String ack = MsgProcesser.getSingleton().onIdleTooLong(session);
                SessionManager.getSingleton().closeSessionAfterAck(session, ack);
            }
        } else if (evt instanceof SecurityCheckCompleteEvent) {
            log.info("Security check has passed");
            SecurityCheckCompleteEvent completeEvt = (SecurityCheckCompleteEvent) evt;
            //登陆成功了，进行session的创建

            ServerSession session = new ServerSession(ctx.channel());
            session.setUser(new UserDTO(completeEvt.getAppId(),completeEvt.getAccount()));
            SessionManager.getSingleton().add(session);

        } else {
            super.userEventTriggered(ctx, evt);
        }
    }


}
